home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 101_01 / xword.c < prev    next >
Text File  |  1985-11-13  |  15KB  |  532 lines

  1.  
  2. /**********************************************************
  3.  ***                            ***
  4.  ***    Copyright (c) 1981 by David M. Fogg        ***
  5.  ***                            ***
  6.  ***        2632 N.E. Fremont            ***
  7.  ***        Portland, OR 97212            ***
  8.  ***                            ***
  9.  ***        (503) 288-3502{HM} || 223-8033{WK}        ***
  10.  ***                            ***
  11.  ***    Permission is herewith granted for non-     ***
  12.  ***    commercial distribution through the BDS C    ***
  13.  ***    User's Group; any and all forms of commercial   ***
  14.  ***    redistribution are strenuously unwished-for.    ***
  15.  ***                            ***
  16.  **********************************************************/
  17.  
  18. /* ---> XWORD.C <--- : Crossword Puzzle Program : Z-19 version
  19.  
  20.    (C) Copyright 1980 by David M. Fogg @ New Day Computing - Portland, OR
  21.  
  22.    9 APR 80 - 1st pass
  23.    25 oct 80: convert to BDS C 1st pass
  24.    26 Oct: add final touches
  25.    28 Oct: convert to VG MT
  26.    29 Oct: chg to oclose() in WRITS:
  27.    31 Oct: fix VG shift arrow prob;
  28.        add dubchk() to READS: & WRITS:;
  29.        chg putadv(..) 2 only move 2 nxt legal loc
  30.    4 Nov: convert back to Z-19/DMF environment
  31.    25 Nov: re-comp w/coin() as BIOS, not BDOS, call (1.4X comp);
  32.        make clue display automagickall
  33.    27 Nov: fix ERASE & READS to disp clues after scrn regen
  34.    3 Dec: chg dubchk() 2 wrk w/ lc 'y'; add scrn regen func;
  35.       improve getext() & reloc query.
  36.  
  37.  * HINTS: answer files are FILNAM.ANS
  38.  *                ANSER array
  39.  *                <1st ACROSS clue
  40.  *                rest of ACROSS clues
  41.  *                <1st DOWN clue
  42.  *                rest of DOWN clues
  43.  *                EOF
  44.  *    Partially filled-out screens are FILNAM.EXT
  45.  *        (user specifies EXT)
  46.  *                SCREEN array current contents
  47.  *
  48.  *    All commands are single locase alfa chars;
  49.  *    ucase alfa are put on screen @ curr position,
  50.  *    & cursor is moved ACROSS or DOWN (current mode).
  51.  *
  52.  *    Any letters put on screen by cheating
  53.  *    ('peek' or 'giveup') are put in locase.
  54.  */
  55.  
  56. #include <std.h>
  57.  
  58. #define MAXIZ    21        /* maximum rows/cols in puzzle */
  59. #define AVLEN    35        /* avg clue length */
  60. #define MAXLEN    65        /* max    "     "    */
  61. #define MXCLUES MAXIZ*MAXIZ/2    /* max # ACROSS+DOWN clues */
  62. #define CLUBS    MXCLUES*AVLEN    /* size of clubuf[] */
  63.  
  64. #define DX    3        /* horiz dist btwn chars */
  65. #define DY    1        /* vert   "    "     "   */
  66. #define XORG    1        /* scrn X-ord of upleft char */
  67. #define YORG    0        /*  "   Y-ord "    "     "   */
  68.  
  69. /*
  70.     ---> command characters <---
  71. */
  72. #define ACROSS    'p'        /* set mode to ACROSS */
  73. #define DOWN    'q'        /*  "   "   "  DOWN */
  74. #define GOBAK    '4'        /* command to move cursor left */
  75. #define GOFWD    '6'        /*    "    "   "     "      right */
  76. #define GOUP    '8'        /*    "    "   "     "      up */
  77. #define GODN    '2'        /*    "    "   "     "      down */
  78. #define TOPLN    't'        /* goto top line in col */
  79. #define BOTLN    'v'        /*  "   bott "     "   "    */
  80. #define INITC    's'        /*  "   init col "  line */
  81. #define FINC    'w'        /*  "   final "  "   "     */
  82. #define PEEK    '7'        /* put anser letter on scrn */
  83. #define UNDO    '9'        /* erase a single letter */
  84. #define ERASE    '3'        /*** erase screen ***/
  85. #define GIVUP    '1'        /*** fill in whole screen ***/
  86. #define WRITS    'u'        /* write scrn to file */
  87. #define READS    'r'        /* read   "  from "   */
  88. #define REGEN    '\t'        /* regenerate screen */
  89. #define QUIT    '5'        /*** quit: exit program ***/
  90. /*
  91.     ---> misc ASCII &c <---
  92. */
  93. #define MT    '.'        /* empty cell on screen */
  94. #define WALL    ' '        /* wall cell */
  95. #define DELIM    '<'        /* delimit anser<ACROSS<DOWN in file */
  96. #define RUBIT     0        /* erase scrn arg to scrini() */
  97. #define RENUIT    -1        /* regen scrn arg to scrini() */
  98. /*
  99.     ---> screen positions <---
  100. */   
  101. #define ACY    22        /* ACROSS clue line */
  102. #define DCY    23        /* DOWN    "    "   */
  103. #define AHX    0        /* ACROSS hdr column */
  104. #define DHX    2        /* DOWN    "    "    */
  105. #define ACX    8        /* ACROSS clue    "    */
  106. #define DCX    8        /* DOWN    "    "    */
  107. #define FNY    0        /* filename line */
  108. #define FNX    68        /*    "     column */
  109. #define PRX    66        /* extension prompt col */
  110. #define PRY    20        /*     "       "    line */
  111. #define INX    65        /* Instructions column */
  112. #define INY    3        /* first Instructions line */
  113. #define L25X    5        /* funkey ID line X-ord */
  114. #define L25Y    24        /*   "    "   "   Y-ord */
  115.  
  116.  
  117. /*
  118.     * * * * * *  G L O B A L S  * * * * * *
  119. */
  120.  
  121. char iobuf[BUFSIZ];         /* file I/O buffer */
  122.  
  123. int rows, cols;        /* rows/cols in curr puzzle */
  124. int crow, ccol;        /* current (cursor) row/column */
  125. int nacc, ndown;       /* # of ACROSS/DOWN clues */
  126. char scrn[MAXIZ][MAXIZ];    /* screen array */
  127. char anser[MAXIZ][MAXIZ];   /* answer array */
  128. char *aclu[MAXIZ][MAXIZ];   /* pointo ACROSS clues in clubuf */
  129. char *dclu[MAXIZ][MAXIZ];   /*     "    DOWN     "   "    "    */
  130. char clubuf[CLUBS];          /* clues buffer */
  131.  
  132.  
  133. /* >>>------------->  M A I N    P R O G R A M  <-------------<<< */
  134.  
  135. main (ac, av)
  136. int ac;
  137. char *av[];
  138. {
  139.    char filnam[12], ansfil[15]; /* file names */
  140.    int ansfd, scrfd;        /* file descriptors */
  141.    char inch;            /* input char from kbd */
  142.    int savr, savc;        /* save crow,ccol */
  143.    char dir;            /* direction/clue flag: a/d */
  144.    int arow, acol, drow, dcol;    /* last ACROSS/DOWN clue cursor lox */
  145.    BOOL errms;
  146.  
  147.    rows = cols = crow = ccol = nacc = ndown = 0;
  148.    arow = acol = drow = dcol = -1;
  149.    errms = NO;
  150.  
  151.    if ((++av, --ac) != 1)
  152.       errxit("usage: xword ansfilnam");
  153.    strcpy(filnam, *av); strcpy(ansfil, *av);
  154.    strcat(ansfil, ".ANS");
  155.    if ((ansfd = fopen(ansfil, iobuf)) == ERROR)
  156.       errxit(".ANS file not found");
  157.  
  158.    getans();       /* read .ANS file & setup clue pointers */
  159.  
  160.    dir = scrini(filnam, NO);    /* initialize screen */
  161. /*
  162.     >>------> MAIN LOOP <------<<
  163. */
  164.    FOREVER {
  165.       cluput(arow, acol, drow, dcol);
  166.       arow = drow = crow;
  167.       acol = dcol = ccol;
  168.       inch = zchar();
  169.       if (errms) {
  170.      ereol(PRX, PRY);
  171.      errms = NO;
  172.       }
  173.       if (isupper(inch))
  174.      putadv(inch, dir);
  175.       else
  176.      switch (inch) {
  177.         case ACROSS:    /* set dir (& print clue) */
  178.            toxy(AHX, ACY); puts("ACROSS:");
  179.            msgat(DHX, DCY, "DOWN:");
  180.            dir = ACROSS;
  181.            break;
  182.         case DOWN:
  183.            toxy(DHX, DCY); puts("DOWN:");
  184.            msgat(AHX, ACY, "ACROSS:");
  185.            dir = DOWN;
  186.            break;
  187.         case GOBAK:     /* move one space left */
  188.            while (torc(crow, --ccol) == WALL);
  189.            break;
  190.         case GOFWD:      /* move one space right */
  191.            while (torc(crow, ++ccol) == WALL);
  192.            break;
  193.         case GODN:         /* move one space down */
  194.            while (torc(++crow, ccol) == WALL);
  195.            break;
  196.         case GOUP:         /* move one space up */
  197.            while (torc(--crow, ccol) == WALL);
  198.            break;
  199.         case TOPLN:     /* move to limit u/d/l/r */
  200.         case BOTLN:
  201.         case INITC:
  202.         case FINC:
  203.            crow = (inch == TOPLN) ? 0 : (inch == BOTLN) ? rows - 1: crow;
  204.            ccol = (inch == INITC) ? 0 : (inch == FINC) ? cols - 1 : ccol;
  205.            while (torc(crow, ccol) == WALL) {
  206.           crow += (inch == TOPLN) - (inch == BOTLN);
  207.           ccol += (inch == INITC) - (inch == FINC);
  208.            }
  209.            break;
  210.         case PEEK:        /* peek: put anser ltr up */
  211.            putadv(tolower(anser[crow][ccol]), dir);
  212.            break;
  213.         case UNDO:        /* erase a single letter */
  214.            putadv(MT, dir);
  215.            break;
  216.         case ERASE:     /* erase screen */
  217.            if (dubchk()) {
  218.           dir = scrini(filnam, RUBIT);
  219.           acol = dcol = arow = drow = -1;
  220.            }
  221.            break;
  222.         case GIVUP:     /* giveup: fillin screen */
  223.            savr = crow; savc = ccol;
  224.            if (dubchk()) {
  225.           for (crow = 0; crow < rows; ++crow)
  226.           for (ccol = 0; ccol < cols; ++ccol)
  227.              if (scrn[crow][ccol] == MT)
  228.             charon(scrn[crow][ccol] = tolower(anser[crow][ccol]));
  229.            }
  230.            torc(savr, savc);
  231.            break;
  232.         case WRITS:     /* write screen to file */
  233.            savr = crow; savc = ccol;
  234.            if (dubchk())
  235.           if ((scrfd = getext(filnam, WRITE)) < 0) {
  236.              msgat(PRX, PRY, "FILE ERR");
  237.              errms = YES;
  238.           }
  239.           else {
  240.              for (crow = 0; crow < rows; ++crow) {
  241.             for (ccol = 0; ccol < cols; ++ccol)
  242.                putc(scrn[crow][ccol], iobuf);
  243.             fputs("\r\n", iobuf);
  244.              }
  245.              oclose(iobuf);
  246.              ereol(PRX, PRY);
  247.           }
  248.            torc(savr, savc);
  249.            break;
  250.         case READS:     /* read screen fro